<?php
/**
 * Класс, реализующий построение форм на основе xml-файлов
 * 
 * @category Phorm
 * @package Form
 * @name /Phorm/Form.php
 * @copyright phorm.ru
 * @since 21.11.2010
 * @author vladimir@kachalov.net
 */

class Phorm_Form extends Zend_Form {
		
	/**
	 * Объект загрузчика
	 * @var Phorm_Bootstrap
	 */
	protected $_boot; 
	
	/**
	 * Конструктор
	 *
	 * @param mixed $files Путь к файлу формы или массив путей относительно папки application/configs)
	 * @param string $section Имя секции (секция общая для всех файлов !!!)
	 * @param mixed $options Дополнительные опции array | Zend_Config
	 * 
	 * @return Zend_Form
	 * @todo Сделать ключи опций регистронезависимыми
	 */
	
	public function __construct($files = null, $section = null, $options = null) {
		
		/**
		 * Получаем объект загрузчика
		 */
		
		$front = Zend_Controller_Front::getInstance();
		$this->_boot = $front->getParam('bootstrap');
		
		/**
		 * Получаем объект конфигурации
		 */
		
		$config = is_null($files) ? array() : Phorm_Config::xml($files,$section,true);
		
		/**
		 * Расширяем конфигурацию
		 */
		
		if($options instanceof Zend_Config) $options = $options->toArray();
		if(is_array($options)) $config = array_merge_recursive($config,$options);
		
		/**
		 * Добавляем наши пути
		 */
		
		$prefixPath = array(
			array('prefix'=>'ZendX_JQuery_Form', 'path'=>'ZendX/JQuery/Form'),
			array('prefix'=>'Phorm_Form',        'path'=>'Phorm/Form'),
			array('prefix'=>'Phorm_JQuery_Form', 'path'=>'Phorm/JQuery/Form'),
		);
		$config['prefixPath'] = isset($config['prefixPath']) && is_array($config['prefixPath']) 
									? array_merge(array_values($config['prefixPath']),$prefixPath) : $prefixPath;
		
		$elementPrefixPath = array(
			array('prefix'=>'Phorm_Filter',  'path'=>'Phorm/Filter',  'type'=>'filter'),
			array('prefix'=>'Phorm_Validate','path'=>'Phorm/Validate','type'=>'validate'),
		);
		$config['elementPrefixPath'] = isset($config['elementPrefixPath']) && is_array($config['elementPrefixPath']) 
											? array_merge(array_values($config['elementPrefixPath']),$elementPrefixPath) : $elementPrefixPath;
		
		/**
		 * Удаляем элементы, если это определено в конфигурации
		 */
		
		if(isset($config['elements']) && is_array($config['elements'])) {
			foreach ($config['elements'] as $elementname=>$element) {
				if(isset($element['options']['isexcluded']) && $element['options']['isexcluded']==1) {
					unset($config['elements'][$elementname]);
					// Удаляем элемент из групп
					if(isset($config['displayGroups']) && is_array($config['displayGroups'])) {
						foreach ($config['displayGroups'] as $groupname=>$group) {
							if(isset($group['elements']) && is_array($group['elements'])) {
								foreach ($group['elements'] as $gr_elementname=>$gr_element) {
									if($gr_elementname===$elementname) {
										unset($config['displayGroups'][$groupname]['elements'][$gr_elementname]);
									}
								}
							}
						}
					}
				}
			}
		}
		
		
		/**
		 * Удаляем группы, в которых нет элементов
		 */
		
		if(isset($config['displayGroups']) && is_array($config['displayGroups'])) {
			foreach ($config['displayGroups'] as $groupname=>$group) {
				if(!isset($group['elements']) || count($group['elements'])===0) {
					unset($config['displayGroups'][$groupname]);
				}
			}
		}
		
		/**
		 * Добавляем класс для формы ui-form
		 */
		
		$config['attribs']['class'] = isset($config['attribs']['class']) ? $config['attribs']['class'] . ' ui-form' : 'ui-form';
		
		/**
		 * Инициализируем объект Zend_Form
		 */
		
		$this->setOptions($config);
		$this->setTranslator($this->_boot->translate);
		$this->init();
		$this->loadDefaultDecorators();
		
		/**
		 * Удаляем декораторы для заголовков в группах, где только один элемент 
		 */
		
		foreach ($this->getDisplayGroups() as $group) {
			$elements = $group->getElements();
			if(count($elements)===1) {
				foreach ($elements as $element) $element->removeDecorator('Label');
			}
		}
		
		/**
		 * Удаляем декораторы у элементов Zend_Form_Element_Hidden и добавляем unescape на описание всех элементов
		 */
		
		foreach ($this->getElements() as $element) {
			if($element->getType()=='Zend_Form_Element_Hidden') {
				$element->removeDecorator('Label');
			}
			if($desc = $element->getDecorator('Description')) {
				$desc->setEscape(false);
			}
		}
		
	}
	
	
	/**
	 * Добавляет яваскрипт на форму
	 *
	 * @param mixed $strings
	 * 
	 * @return Zend_Form
	 */
	
	public function setJavascript($strings) {
		
		if(!is_array($strings)) $strings = array($strings);
		
		foreach ($strings as $js) $this->_boot->jquery->addOnLoad($js);
		
		return $this;
		
	}
	
	
	/**
	 * Добавляет файлы яваскриптов на форму
	 *
	 * @param mixed $files
	 * 
	 * @return Zend_Form
	 */
	
	public function setJavascriptFile($files) {
		
		if(!is_array($files)) $files = array($files);
		
		foreach ($files as $file) $this->_boot->jquery->addJavascriptFile(trim($file));
		
		return $this;
		
	}
	
	
	/**
	 * Валидирует данные формы (враппер для родительского isValid с передачей в шаблон общего сообщения в случае ошибок валидации)
	 *
	 * @param array $data Массив данных для проверки
	 * @return boolean
	 */
	
	public function isValid($data) {
		
		if(parent::isValid($data)) {
			
			return true;	
				
		} else {
			
			$view = $this->getView();
			$translate = $this->getTranslator();
			$view->assign('Errors',array($translate->_('При заполнении формы были обнаружены ошибки')));
				
		}
		
		return false;
		
	}
	
}
